package com.janyee.buddha.view

import android.animation.Animator
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.PointF
import android.support.v4.view.animation.FastOutLinearInInterpolator
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.widget.FrameLayout
import com.janyee.buddha.PowInterpolator
import com.janyee.buddha.adapter.IBookFliperAdapter
import java.util.*


/**
 * Created by kmlixh on 17/12/14.
 * useage:
 * TextTest
 */

open class BookFliper : FrameLayout, Animator.AnimatorListener {
    var isTouchable = true
    private var type = 0//0无状态，1上一页滚动，2为当前页滚动
    private var viewStatus=0//0，显示当前页，1，显示上一页，2，显示下一页
    private var downPoint: PointF = PointF(0f, 0f)
    private var adapter: IBookFliperAdapter? = null
    private val FI = 1.61803398f
    private var XS = 0f
    private var XM = 0f
    private var YS = 0f
    private var YM = 0f
    private var lastMoved: PointF = PointF(0f, 0f)
    private var oldMoved: PointF = PointF(0f, 0f)
    private var timer = Timer()
    var longClickTask: TimerTask? = null

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)

    fun callMyClick() {
        if (type == 0) {
            if ((downPoint.x < XM && downPoint.y <= YS) || downPoint.x <= XS) {
                Log.e("===", "callMyClick left")
                if (adapter!!.hasPrevious()) {
                    type = 1
                    viewStatus = 1
                    animationPrevious(0)
                }
            } else if (downPoint.x > XS && downPoint.x < XM && downPoint.y > YS && downPoint.y < YM) {
                Log.e("===", "callMyClick center")

            } else if (downPoint.x > XS || (downPoint.x >= XM && downPoint.y >= YM)) {
                Log.e("===", "callMyClick right")
                if (adapter!!.hasNext()) {
                    type = 2
                    viewStatus = 2
                    animationNext(-width)
                }
            }
        }
    }

    fun longClickIt() {
        kotlin.run {
            if (longClickTask != null) {
                longClickTask!!.cancel()
            }
            var longClickTask = object : TimerTask() {
                override fun run() {
                    Log.e("=====", "fliper longCLick")
                    isTouchable = false
                    adapter!!.callLongClick()
                }
            }
            this.longClickTask = longClickTask
            timer.schedule(longClickTask, 300)
        }
    }

    fun longClickCancel() {
        if (longClickTask != null) {
            longClickTask!!.cancel()
        }
        longClickTask = null
    }

    var pred = true

    override fun onTouchEvent(event: MotionEvent): Boolean {
        var result = true
        if (isTouchable) {
            when (event.action) {
                MotionEvent.ACTION_DOWN -> {
                    timer = Timer()
                    timer.schedule(object : TimerTask() {
                        override fun run() {
                            isTouchable = false
                            adapter!!.callLongClick()
                        }
                    }, 800)
                    Log.e("===", "parent down")
                    type = 0
                    downPoint = PointF(event.x, event.y)
                    lastMoved = downPoint
                    return true
                }
                MotionEvent.ACTION_MOVE -> {
                    oldMoved = lastMoved
                    if (type == 0 && Math.abs(event.x - downPoint.x) > 15) {
                        timer.cancel()
                        if (event.x > downPoint.x) {
                            type = 1
                        } else {
                            type = 2
                        }
                        Log.e("====", "type:" + type)
                    }
                    if (type != 0) {
                        if (type == 2 && adapter!!.hasNext()) {
                            var marginParam = adapter!!.current().layoutParams as MarginLayoutParams
                            marginParam.leftMargin += (event.x - lastMoved.x).toInt()
                            Log.e("=====", "margin:" + marginParam.leftMargin + "----" + event.x)
                            adapter!!.current().layoutParams = marginParam
                            adapter!!.next().postInvalidate()
                            adapter!!.current().requestLayout()
                        } else if (type == 1 && adapter!!.hasPrevious()) {
                            var marginParam = adapter!!.previous().layoutParams as MarginLayoutParams
                            marginParam.leftMargin += (event.x - lastMoved.x).toInt()
                            Log.e("=====", "margin:" + marginParam.leftMargin + "----" + event.x)
                            adapter!!.previous().layoutParams = marginParam
                            adapter!!.previous().requestLayout()
                        }
                        lastMoved = PointF(event.x, event.y)
                    }
                }
                MotionEvent.ACTION_UP -> {
                    if (type == 2 && adapter!!.hasNext()) {
                        var endMargin = 0
                        if (event.x > oldMoved.x) {
                            endMargin = 0
                            viewStatus = 0
                        } else {
                            endMargin = -width
                            viewStatus = 2
                        }
                        animationNext(endMargin)
                    } else if (type == 1 && adapter!!.hasPrevious()) {
                        var endMargin = 0
                        if (event.x > oldMoved.x) {
                            viewStatus = 1
                            endMargin = 0
                        } else {
                            endMargin = -width
                            viewStatus = 0
                        }
                        animationPrevious(endMargin)
                    } else if (type == 0) {
                        timer.cancel()
                        callMyClick()
                    }
                }

            }
        }
        return result
    }


    fun animationPrevious(endMargin: Int) {
        isTouchable = false
        val animation = ValueAnimator.ofInt((adapter!!.previous().layoutParams as MarginLayoutParams).leftMargin, endMargin)
        animation.duration = 400
        animation.addUpdateListener({ ani: ValueAnimator ->
            (adapter!!.previous().layoutParams as MarginLayoutParams).leftMargin = ani.animatedValue as Int
            adapter!!.previous().requestLayout()
            if (Math.abs(ani.animatedValue as Int) < (width / 5) && pred) {
                adapter!!.pagePreviousPre()
                pred = false
            }

        })
        animation.addListener(this)
        animation.start()
    }

    fun animationNext(endMargin: Int) {
        isTouchable = false
        val animation = ValueAnimator.ofInt((adapter!!.current().layoutParams as MarginLayoutParams).leftMargin, endMargin)
        animation.duration = 400
        animation.addUpdateListener({ ani: ValueAnimator ->
            (adapter!!.current().layoutParams as MarginLayoutParams).leftMargin = ani.animatedValue as Int
            adapter!!.current().requestLayout()
        })
        animation.addListener(this)
        animation.start()
    }

    fun setAdapter(adapter: IBookFliperAdapter) {
        this.adapter=adapter
        adapter.init(this)
    }

    var needResetParam = true
    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        Log.e("====", "on layout")
        XM = width * (FI - 1)
        XS = XM * (FI - 1)
        YM = height * (FI - 1)
        YS = YM * (FI - 1)

        var nextParam = adapter!!.next().layoutParams as MarginLayoutParams

        var currentParam = adapter!!.current().layoutParams as MarginLayoutParams
        var previousParam = adapter!!.previous().layoutParams as MarginLayoutParams
        if (needResetParam) {
            Log.e("===","refresh Param")
            needResetParam = false
            nextParam.leftMargin = 0
            currentParam.leftMargin = 0
            previousParam.leftMargin = -r + l
            adapter!!.next().layoutParams = nextParam
            adapter!!.current().layoutParams = currentParam
            adapter!!.previous().layoutParams = previousParam
        }
        adapter!!.next().layout(l, t, r, b)
        adapter!!.current().layout(l + currentParam.leftMargin, t, r + currentParam.leftMargin, b)
        adapter!!.previous().layout(l + previousParam.leftMargin, t, r + previousParam.leftMargin, b)
    }
    override fun onAnimationEnd(animation: Animator?) {
        isTouchable = true
        pred = true
        Log.e("====", "Ani End:" + viewStatus + "===" + type)
        type = 0
        needResetParam = true
        if (viewStatus == 1) {
            adapter!!.pagePrevious()
        } else if (viewStatus == 2) {
            adapter!!.pageNext()
        }

    }

    override fun onAnimationStart(animation: Animator?) {

    }

    override fun onAnimationRepeat(animation: Animator?) {
    }

    override fun onAnimationCancel(animation: Animator?) {
    }
}